﻿using System;
using System.Threading;
using ThreadSyncron.Utils.Utils.Interfaces;

namespace ThreadSyncron.Utils
{
	public class TSPool
	{

		private TSPool()
		{
		}

		private IInfoControl InfoControl
		{
			get;
			set;
		}

		#region TSPool Singleton Thread safe

		static private TSPool instance = null;
		static volatile object padlock = new object();

		public static TSPool Instance
		{
			get
			{
				if (instance == null)
					lock (padlock)
					{
						if (instance == null)
							instance = new TSPool();
					}
				return instance;
			}
		}

		#endregion

		#region ThreadsCount Singleton Thread safe

		private long threadsCount { get; set; }

		private readonly object threadsCountpadlock = new object();

		public long GetThreadsCount()
		{
			lock (threadsCountpadlock)
			{
				return threadsCount;
			}
		}

		public void AddThreadsCount(long c)
		{
			{
				threadsCount += c;
			}
		}

		#endregion

		public void AddThread(Func<IIOActionParameters, IIOActionParameters> action, string ActionName, Action<IIOActionParameters> EndAction, IIOActionParameters inParams)
		{
			OnStartThread(ActionName);
			Thread t = new Thread(() =>
			                      	{
			                      		IIOActionParameters outParams = action(inParams);
										if (EndAction != null) EndAction(outParams);
			                      		OnFinishThread(ActionName);
			                      	});
			t.Start();
		}

		private void OnStartThread(string ActionName)
		{
			lock (threadsCountpadlock)
			{
				if (GetThreadsCount() == 0)
				{
					InfoControl.ShowInfoControl();
				}
				AddThreadsCount(1);
			}
			InfoControl.ShowMessageText(string.Format("Thread {0} started...", ActionName));
		}

		private void OnFinishThread(string ActionName)
		{
			lock (threadsCountpadlock)
			{
				AddThreadsCount(-1);
				InfoControl.ShowMessageText(string.Format("Thread {0} finished.", ActionName));
				if (GetThreadsCount() == 0)
				{
					InfoControl.HideInfoControl();
				}
			}
		}

		public void Init(IInfoControl infoControl)
		{
			this.InfoControl = infoControl;
			this.InfoControl.Init();
		}
	}
}
